\documentclass[12pt]{article}
\usepackage{times}
\usepackage{graphicx}
\usepackage{sidecap}
\usepackage{wrapfig}
\usepackage{fancyhdr}
\pagestyle{fancy}
\renewcommand{\baselinestretch}{1.2}
\newenvironment{mylisting}
{\begin{list}{}{\setlength{\leftmargin}{1em}}\item\scriptsize\bfseries}
{\end{list}}
\newenvironment{mylisting2}
{\begin{list}{}{\setlength{\leftmargin}{1em}}\item\scriptsize\bfseries}
{\end{list}}

%%% This file is Open Content

\begin{document}
	\textbf{{\Huge NESLisp}}
{\center{Dec 29, 2011, 
	Johan Ceuppens, Theo D'Hondt - Vrije Universiteit Brussel}}
\\
{\large{\textbf{\center Abstract}}}
\\
\\
\section{\large Introduction}



\begin{mylisting}
\begin{verbatim}

	
#ifndef _MOOSE_H_
#define _MOOSE_H_

#define BUFSIZE 1024
#include "stack.h"

#define LOOP "loop"
#define WHEN "when"
#define DEFUN "defun"
#define IF "if"
#define IFELSE "0ifelse"
#define IFTHIRD "2ifelse"
#define WHENELSE "1whenelse"

Stack *stack_global;
int labelcounter;
#endif
#ifndef _STACK_H_
#define _STACK_H_

typedef struct stackel { char *elt; char *name; struct stackel *next; } StackElt;
typedef struct stack { int length; StackElt *stack; } Stack; 



#endif
#ifndef _STORAGE_H_
#define _STORAGE_H_
#define FUNCSTACKSIZE 1024
typedef struct functionstackelt {int (*f)(char *, char *); char *arg1; char *arg2;} FunctionstackElt;  
typedef FunctionstackElt *Functionstack[FUNCSTACKSIZE]; 
int functionstackpointer_global;
Functionstack functionstack_global;

int store_function(int (*f)(char *, char *), char *, char *);
int emit_functions();

#endif
/*
# Copyright (C) Johan Ceuppens 2009,2010 
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 2 of the License, or
# (at your option) any later version.

# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.

# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef _NESCC_SYMTAB_H_
#define _NESCC_SYMTAB_H_

/* list */

typedef struct list { int length; } List; 

/* symboltable.c */
enum symtabtypes { INTEGER = 100, CHAR = 201, STRING = 302, FLOAT = 403, NIL = 504, FUNC = 605, LIST = 707, FUNCARG = 808, LOOPARG = 909, }; 
typedef struct symtabelt { int pn /*pointername*/; int address; int type; int Integer; float Float; char Character; char *String; List *List; void *Null;} SymtabElt;

typedef SymtabElt *Symtab;

typedef struct symtabnameelt { char *name; int address; } SymtabNameElt;
typedef SymtabNameElt *SymtabName;

//#define HEAPSIZE 1024
#define HEAPSIZE 65665

Symtab symtab_global[HEAPSIZE];
SymtabName symtabname_global[HEAPSIZE];
int heappointername_global;
int heapmaxname_global;
int heappointer_global;
int heapmax_global;
int make_symtab ();

/* gets */

char *get1(char *str);

#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>


int utility_skip_whitespace_newlines_parens(const char **lispfilecontents, const int lispfilelength, int *index) 
{
	int j = 0;
	char c;
	for (j = 0; *index < lispfilelength && ((c = (*lispfilecontents)[(*index)]) == '\n' || c == ' ' || c == '('); j++) {
		(*index) ++;
	}
	return 1;
}

int utility_skip_whitespace_newlines(const char **lispfilecontents, const int lispfilelength, int *index) 
{
	int j = 0;
	char c;
	for (j = 0; *index < lispfilelength && (c = (*lispfilecontents)[(*index)]) == '\n' || c == ' '; j++) {
		(*index) ++;
	}
	return 1;
}

int comparealpha(char *needle, char *haystack)
{
	int i = 0;



	if (strlen(needle) <= strlen(haystack)) { 
	for (i = 0; i < strlen(needle); i++) {
		if ((haystack[i] >= 65 && haystack[i] <= 90) || (haystack[i] >= 97 && haystack[i] <= 122))
			if (haystack[i] == needle[i])
					continue;	
		else
			break;
	}
	} else {
	for (i = 0; i < strlen(haystack); i++) {
		if ((haystack[i] >= 65 && haystack[i] <= 90) || (haystack[i] >= 97 && haystack[i] <= 122))
			if (haystack[i] == needle[i])
					continue;	
		else
			break;

	}
	}
	return i;
}


int getnargs(char *str) 
{
	int i = 0, nargs = 0;
	for (i = 0; i < strlen(str); i++) {
		if (str[i] == ' ') {
			if (str[i+1] == ' ') continue;
			nargs++;
			for (; i < strlen(str) && str[i] != ' ' && str[i] != '\n' && str[i] != '\0' && str[i] != ')' ; i++) 
				;		
		}
	}
	return nargs;
}

int getarg_until_parens(const char **str, int *len, char **retstr)
{
	int i = 0, j = 0;
	(*retstr) = (char *)malloc(strlen(*str));
	memset((*retstr),0,strlen(*str));
	for (j = 0, i = *len; i < strlen(*str); i++, j++) {
		if ((*str)[i] == ')')
			break;		
		else {
			(*retstr)[j] = (*str)[i];
		}
	}
	(*retstr)[j] = '\0';
	if ((*retstr) == (char *)0) retstr = NULL;	
	*len = i;	
	return 0;
}

int getarg(const char **str, int *len, char **retstr)
{
	int i = 0, j = 0;
	(*retstr) = (char *)malloc(strlen((*str)));
	memset((*retstr),0,strlen((*str)));
	for (j = 0, i = *len; i < strlen((*str)); i++, j++) {
		if ((*str)[i] == ' ' || (*str)[i] == ')')
			break;		
		else {
			(*retstr)[j] = (*str)[i];
		}
	}
	(*retstr)[j] = '\0';
	if ((*retstr) == (char *)0) retstr = NULL;	
	*len = i;	
	return 0;
}

/* string functions*/

int utility_islist(char *str)
{
	int i = 0, nlp = 0, nrp = 0;
	for (i = 0; i < strlen(str); i++) {
		if (str[i] == '(') nlp++;
		if (str[i] == ')') nrp++;
	}
	if (nlp > 1 )// nlp == nrp)
		return 1;
//	if ((nlp == nrp + 1 || nlp == nrp) && nlp > 0 && nrp > 0)//FIXME >= nrp
	//	return 1;
	else
		return -1; /* -1 if list is not closed and sublists are not closed */ 
}


int utility_isalpha(char *str)
{
	int i = 0;
	for (i = 0; i < strlen(str); i++)
		if (!isalpha(str[i])) break;
	if (i < strlen(str))
		return -1;
	else
		return 0;

}
int utility_isdigit(char *str)
{
	int i = 0;
	for (i = 0; i < strlen(str); i++)
		if (!isdigit(str[i])) break;
	if (i < strlen(str))
		return -1;
	else
		return 0;

}


/* symtab extracters */

int getint(char *str, int *len)
{

	int ret = 0;
	int i = 0, k = 0;
	int j = 0, l = 0, m = 0;
	for (j = *len; j >= 0 && (str[j] < 48 || str[j] >= 58); j--)
		;	
	for (i = j; i >= 0 && str[i] != ' ' && str[i] != ')'; i--)//NOTE ')' because of args of function 
		;	
	i++;		
	for (k = j, l = 0; k >= i ; k--, l++)
		if (l == 0) ret += (str[k]-48); else ret += (str[k]-48)*(int)(powf((float)10,(float)l));		
	*len = j-1;
	return ret; 
}

int getintsolo(char *str)
{
	int ret = 0, j = 0, i = 0, k = 0, l = 0;
	for (i = 0; i < strlen(str) && (str[i] < 48 || str[i] >= 58); i++) 
		;	
	for (j = strlen(str); j >= 0; j--) 
		;
	for (k = j, l = 0; k >= i; k--, l++)
		if (l == 0) ret += (str[k]-48); else ret += (str[k]-48)*(int)(powf((float)10,(float)l));		

	return 0; 
}


int getargstring(char *str, int *len, char **retstr)
{
	int flagi; 
	int ret = 0;
	int i = 0, k = 0;
	int j = 0, l = 0, m = 0;
	(*retstr) = (char *)malloc(strlen(str));
	memset((*retstr),0,strlen(str));
	for (j = *len, flagi = *len; j >= 0;  j--) {
		if (j == 0)
			break; 
		if (str[j] == ')')
			flagi = j; 

	}
	for (i = j; i >= 0 && str[i] != ' '; i--) 
		;	
	i++;		
	for (k = flagi, l = 0; k >= i ; k--, l++) {
		(*retstr)[l] = str[k];		
	}	
	*len = j-1;
	return 0; 
}

int getstring(char **str, int *len, char **retstr)
{

	int ret = 0;
	int i = 0, k = 0;
	int j = 0, l = 0, m = 0;
	(*retstr) = (char *)malloc(strlen(*str));
	memset((*retstr),0,strlen(*str));
	for (j = *len; j >= 0 && (((*str)[j] == ')' || (*str)[j] == ' ' || (*str)[j] == '(')); j--)
		;	
	for (i = j; i >= 0 && (*str)[i] != ' '; i--)
		;	
			
	i++;

	for (k = i, l = 0; k <= j && k < strlen(*str); k++, l++)
	{
		(*retstr)[l] = (*str)[k];
	}	
	*len = j-1;
	return 0; 
}

int getstringsolo(char *str, char *retstr)
{
	int ret = 0, j = 0, i = 0, k = 0, l = 0;
	for (i = 0; i < strlen(str) && ((str[i] >= 65 && str[i] <= 90) || (str[i] >= 97 && str[i] <= 122) || str[i] == ' '); i++) 
		;	
	for (k = i, l = 0; k < strlen(str)-1; k++, l++)//NOTE the bracket at the end
		retstr[l] = str[k];

	return 0; 
}


#include "moose.h"
#include "symboltable.h"

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int as1_write_functionjump(const char *name, const char **lispfilecontents, int *lispfileindex)
{
	FILE *fp;
	int i = 0,j = 0;
	char *opexp, *str;
	printf("writing function jump to %s...\n", name);	
	//utility_skip_whitespace_newlines(lispfilecontents, strlen(*lispfilecontents), lispfileindex); 
	getarg_until_parens(lispfilecontents, lispfileindex, &opexp);
	printf("writing %s...\n", opexp);	


	if ((fp = fopen("./code.s", "a+")) < 0) {

		printf("neslisp error - Cannot open code output file\n");
		exit(99);

	}

	if (fseek(fp, 0, SEEK_END) < 0) {

		printf("neslisp error - Cannot seek in code output file\n");
		exit(99);
	}
	for (j = 0; i < strlen(opexp); j++, i++) {
	if (getarg(&opexp, &i, &str) == 0) {
		
		printf("============%d\n", atoi(str));
		if (utility_isdigit(str) == 0) {
			fprintf(fp, "ldx #%d\n", atoi(str));
			fprintf(fp, "stx $%d\n", 3000+j);
		} else if (utility_isalpha(str) == 0) {
			SymtabElt *e = NULL;
			get_symtabname(&str, &e);	
			fprintf(fp, "ldx $%d\n", e->address);
			fprintf(fp, "stx $%d\n", 3000+j);
		} else if (utility_islist(str) == 0) {
			as1_write_list(str,opexp); 
		} else {
			fprintf(fp, "ldx $%d\n", 6000);//FIXME +j 6002 etc.;
			fprintf(fp, "stx $%d\n", 3000+j);
		}	/*FIXME	
		} else {
			fprintf(stdout, "% function % : unknown argument \n");
		}*/
	}
	}
	fprintf(fp, "jmp %s\n", name);
	fclose(fp);
	return 1;
}



int as1_write_operator_plus(const char **lispfilecontents, int *lispfileindex)
{
	FILE *fp;
	int i,j = 0;
	char *opexp;
	utility_skip_whitespace_newlines(lispfilecontents, strlen(*lispfilecontents), lispfileindex); 
	getarg_until_parens(lispfilecontents, lispfileindex, &opexp);//FIXME *
	printf("writing operator +...\n");	


	if ((fp = fopen("./code.s", "a+")) < 0) {

		printf("neslisp error - Cannot open code output file\n");
		exit(99);

	}

	if (fseek(fp, 0, SEEK_END) < 0) {

		printf("neslisp error - Cannot seek in code output file\n");
		exit(99);

	}
	fprintf(fp, "sta #0\n");

	for (i = strlen(opexp); i >= 0; i--) {//NOTE opexp has been chomped : -2
	
	char *str;
	getstring(&opexp, &i,&str);
	//printf("str=%s\n",str);

	if (utility_isdigit(str) == 0) {	
		int n = atoi(str);
	fprintf(fp, "lda #%d\n", n);
	fprintf(fp, "adc $%d\n", 1000);//FIXME j
	fprintf(fp, "sta $%d\n", 1000);
	} else if (utility_isalpha(str) == 0) {	
		SymtabElt *se = NULL;//FIXME return it;
		get_symtabname(&str, &se);
		if (se == NULL) {
			fprintf(stdout, "%operator + % undefined identifier : %s \n", str);
		} /*FIXME else if (se->type != INTEGER && se->type != FLOAT && se->type != LOOPARG && se->type != FUNCARG) {
			fprintf(stdout, "%operator + % wrong type argument : %s %s\n", opexp, opexp);	
			//exit(99);
		} */ else {
			fprintf(fp, "lda $%d\n", se->address);
			fprintf(fp, "adc $%d\n", 1000);
			fprintf(fp, "sta $%d\n", 1000);
		}			
	} else if (utility_islist(str) == 0) {
		as1_write_list(str,opexp);
	} 
	j++;
	i--;
	free(str);
	}
	fprintf(fp, "sta $%d\n", 6000);
	fclose(fp);
	return 0;
}





int as1_write_operator_minus(const char **lispfilecontents, int *lispfileindex)
{
	FILE *fp;
	int i,j = 0;
	char *opexp;
	utility_skip_whitespace_newlines(lispfilecontents, strlen(*lispfilecontents), lispfileindex); 
	getarg_until_parens(lispfilecontents, lispfileindex, &opexp);//FIXME *
	printf("writing operator -...\n");	


	if ((fp = fopen("./code.s", "a+")) < 0) {

		printf("neslisp error - Cannot open code output file\n");
		exit(99);

	}

	if (fseek(fp, 0, SEEK_END) < 0) {

		printf("neslisp error - Cannot seek in code output file\n");
		exit(99);

	}
	fprintf(fp, "sta #0\n");

	for (i = strlen(opexp); i >= 0; i--) {//NOTE opexp has been chomped : -2
	
	char *str;
	getstring(&opexp, &i,&str);
	printf("str=%s\n",str);

	if (utility_isdigit(str) == 0) {	
		int n = atoi(str);
	fprintf(fp, "lda #%d\n", n);
	fprintf(fp, "sbc $%d\n", 1000);//FIXME j
	fprintf(fp, "sta $%d\n", 1000);
	} else if (utility_isalpha(str) == 0) {	
		SymtabElt *se = NULL;//FIXME return it;
		get_symtabname(&str, &se);
		if (se == NULL) {
			fprintf(stdout, "%operator - % undefined identifier : %s %s\n", str, str);
		} else if (se->type != INTEGER && se->type != FLOAT && se->type != FUNCARG && se->type != LOOPARG) {
			fprintf(stdout, "%operator - % wrong type argument : %s\n", opexp);	
			//exit(99);
		} else {
			fprintf(fp, "lda $%d\n", se->address);
			fprintf(fp, "sbc $%d\n", 1000);
			fprintf(fp, "sta $%d\n", 1000);
		}			
	} else if (utility_islist(str) == 0) {
		as1_write_list(str,opexp);
	} 
	j++;
	i--;
	free(str);
	}
	fprintf(fp, "sta $%d\n", 6000);
	fclose(fp);
	return 0;
}



int as1_write_ifsecondclauseend(char *s, int labelc)
{
	FILE *fp;
	int i = 0, j = 0;
	printf("writing if second clause end...");	

	if ((fp = fopen("./code.s", "a+")) < 0) {

		printf("neslisp error - Cannot open code output file\n");
		exit(99);

	}

	if (fseek(fp, 0, SEEK_END) < 0) {

		printf("neslisp error - Cannot seek in code output file\n");
	}

	fprintf(fp, "%s%d:\n", "compare", labelc);//NOTE address 6000 FIXME1 loop var label must be fixed	
	fclose(fp);
}


int as1_write_iffirstclauseend(char *s, int labelc)
{
	FILE *fp;
	int i = 0, j = 0;
	printf("writing if first clause end...");	

	if ((fp = fopen("./code.s", "a+")) < 0) {

		printf("neslisp error - Cannot open code output file\n");
		exit(99);

	}

	if (fseek(fp, 0, SEEK_END) < 0) {

		printf("neslisp error - Cannot seek in code output file\n");
	}
	//JUMP
	//labelcounter++;
	fprintf(fp, "jmp %s%d\n", "compare", labelc);//NOTE address 6000 FIXME1 loop var label must be fixed	
	fprintf(fp, "%s%d:\n", "compare", labelc);//NOTE address 6000 FIXME1 loop var label must be fixed	
	//labelcounter++;
	fclose(fp);
}


int as1_write_whenendsecond()
{
	FILE *fp;
	int i = 0, j = 0;
	printf("writing when end...");	

	if ((fp = fopen("./code.s", "a+")) < 0) {

		printf("neslisp error - Cannot open code output file\n");
		exit(99);

	}

	if (fseek(fp, 0, SEEK_END) < 0) {

		printf("neslisp error - Cannot seek in code output file\n");
	}

	fprintf(fp, "compare%d:\n", labelcounter);//NOTE address 6000 FIXME1 loop var label must be fixed	
	fclose(fp);
}

int as1_write_ifclausethird(char *s, int labelc)
{
	FILE *fp;
	int i = 0, j = 0;
	printf("writing when end...");	

	if ((fp = fopen("./code.s", "a+")) < 0) {

		printf("neslisp error - Cannot open code output file\n");
		exit(99);

	}

	if (fseek(fp, 0, SEEK_END) < 0) {

		printf("neslisp error - Cannot seek in code output file\n");
	}
	//JUMP2
	fprintf(fp, "compare%d:\n", labelc);//NOTE address 6000 FIXME1 loop var label must be fixed	
	fclose(fp);
}


int as1_write_whenend()
{
	FILE *fp;
	int i = 0, j = 0;
	printf("writing when end...");	

	if ((fp = fopen("./code.s", "a+")) < 0) {

		printf("neslisp error - Cannot open code output file\n");
		exit(99);

	}

	if (fseek(fp, 0, SEEK_END) < 0) {

		printf("neslisp error - Cannot seek in code output file\n");
	}

	fprintf(fp, "sta $%d\n", 6000);//NOTE address 6000 FIXME1 loop var label must be fixed	
	fprintf(fp, "when%d:\n", labelcounter);//NOTE address 6000 FIXME1 loop var label must be fixed	
	fclose(fp);
}



int as1_write_loopend()
{
	FILE *fp;
	int i = 0, j = 0;
	printf("writing loop end...");	

	if ((fp = fopen("./code.s", "a+")) < 0) {

		printf("neslisp error - Cannot open code output file\n");
		exit(99);

	}

	if (fseek(fp, 0, SEEK_END) < 0) {

		printf("neslisp error - Cannot seek in code output file\n");
	}

	fprintf(fp, "ldx $%d\n", 1500);//NOTE address 1500	
	fprintf(fp, "inx\n");//NOTE on address 1500	
	fprintf(fp, "stx $%d\n", 1500);//NOTE addres 1500	
	fprintf(fp, "cmp $%d\n", 1502);//NOTE address 1502
	fprintf(fp, "bne %s%d\n", LOOP, labelcounter);//FIXME1 loop var label must be fixed	

}

/*

Function args are stored at 3000
*/

int as1_write_loop(const char **lispfilecontents, int *lispfileindex)
{
	FILE *fp;
	int i = 0;
	char *forname, *fromname, *toname, *doname, *minimumname, *maximumname;
	char *args;
	char *opexp;


	/* read in "for" */

	utility_skip_whitespace_newlines(lispfilecontents, strlen(*lispfilecontents), lispfileindex); 
	getarg(lispfilecontents, lispfileindex, &forname);

	/* read in opexp, counter variable */

	utility_skip_whitespace_newlines(lispfilecontents, strlen(*lispfilecontents), lispfileindex); 
	getarg(lispfilecontents, lispfileindex, &opexp);

	SymtabElt *se = (SymtabElt *)malloc(sizeof(SymtabElt));
	add_symtabname(&opexp, &se); //NOTE add a single name (loop arg)
	//se->Integer = atoi(minimumname);
	/* read in "from" */

	utility_skip_whitespace_newlines(lispfilecontents, strlen(*lispfilecontents), lispfileindex); 
	getarg(lispfilecontents, lispfileindex, &fromname);
	
	/* read in minimum value 1 */

	utility_skip_whitespace_newlines(lispfilecontents, strlen(*lispfilecontents), lispfileindex); 
	getarg(lispfilecontents, lispfileindex, &minimumname);
	
	/* read in "to" */

	utility_skip_whitespace_newlines(lispfilecontents, strlen(*lispfilecontents), lispfileindex); 
	getarg(lispfilecontents, lispfileindex, &toname);
	
	/* read in maximum value 2 */

	utility_skip_whitespace_newlines(lispfilecontents, strlen(*lispfilecontents), lispfileindex); 
	getarg(lispfilecontents, lispfileindex, &maximumname);
	
	/* read in "do" */

	utility_skip_whitespace_newlines(lispfilecontents, strlen(*lispfilecontents), lispfileindex); 
	getarg(lispfilecontents, lispfileindex, &doname);
	
	printf("writing loop...%s %s %s %s %s %s %s\n", forname, opexp, fromname, minimumname, toname, maximumname, doname);	



	if ((fp = fopen("./code.s", "a+")) < 0) {

		printf("neslisp error - Cannot open code output file\n");
		exit(99);

	}

	if (fseek(fp, 0, SEEK_END) < 0) {

		printf("neslisp error - Cannot seek in code output file\n");
		exit(99);

	}
	/* counter variable , see above */

	//char *value;
	//get_symtabname(&opexp, se);
	fprintf(fp, "ldx #%d\n", atoi(minimumname));	
	fprintf(fp, "stx $%d\n", se->address);	
	
	fprintf(fp, "ldx #%d\n", atoi(minimumname));	
	fprintf(fp, "stx $%d\n", 1500);	
	fprintf(fp, "%s%d:\n", LOOP,labelcounter);;//FIXME unique label	

	if (opexp == NULL)
		return 0;
/*
	if (opexp != NULL && utility_isalpha(opexp) == 0) { //NOTE str is loop arg
		SymtabElt *e = (SymtabElt *)malloc(sizeof(SymtabElt));
		//e->address = 3000 + j;
		//e->pn = 3000 + j;
		e->type = LOOPARG;
		e->Integer = NIL;	
		e->Float = NIL;	
		e->Character = 0;//NIL;	
		e->Null = 0;//NIL;	
		e->String = NULL;//NIL;		
		e->List = NULL;			
		add_symtabname(&opexp, &e); //NOTE add a single name (func arg)
*/		//fprintf(fp, "stx $%d\n", e->address);;//loop counter init
		fprintf(fp, "ldx #%d\n", atoi(maximumname));	
		fprintf(fp, "stx $%d\n", 1502);//NOTE addres 1500	
//	}
	fclose(fp);
//	free(str);
	return 0;
}

int as1_write_functionend(char **name)
{
	FILE *fp;
	int i = 0;

	
	printf("writing defun end..\n");	


	if ((fp = fopen("./code.s", "a+")) < 0) {

		printf("nescc error - Cannot open code output file\n");
		exit(99);

	}

	if (fseek(fp, 0, SEEK_END) < 0) {

		printf("nescc error - Cannot seek in code output file\n");
		exit(99);

	}

	fprintf(fp, "%s:\n", *name);	

	fclose(fp);
	return 0;
}

int as1_write_functionheader(const char **lispfilecontents, int *lispfileindex)
{
	FILE *fp;
	int i = 0;
	char *name;
	char *args;
	char *opexp;

	utility_skip_whitespace_newlines_parens(lispfilecontents, strlen(*lispfilecontents), lispfileindex); 
	getarg(lispfilecontents, lispfileindex, &name);
	utility_skip_whitespace_newlines_parens(lispfilecontents, strlen(*lispfilecontents), lispfileindex); 
	getarg_until_parens(lispfilecontents, lispfileindex, &opexp);
	
	printf("writing defun...opexp=%s\n",opexp);	


	if ((fp = fopen("./code.s", "a+")) < 0) {

		printf("nescc error - Cannot open code output file\n");
		exit(99);

	}

	if (fseek(fp, 0, SEEK_END) < 0) {

		printf("nescc error - Cannot seek in code output file\n");
		exit(99);

	}

	//fprintf(fp, "%s:\n", name);	

	SymtabElt *se = (SymtabElt *)malloc(sizeof(SymtabElt));
	se->type = FUNC;
	//FIXME type etc. of se	

	se->address = heapmax_global;
	heapmax_global += 2;
	se->pn = se->address;

	add_symtabname(&name, &se);
	/* jump out if there are no arguments */
	if (opexp == NULL)
		return 0;
	/* put all arguments in str */	
	char *str;// = (char *)malloc(1024);
	/*for (i = strlen(opexp); i >= 0; i--) {
		getargstring(opexp, &i, &str);
	}*/
	/* extract all single arguments out of str */
	char *str2;
	int j = 0;
	for (i = 0, j = 0; i < strlen(str)-1; i++, j++) {
		
		getarg(&opexp, &i, &str2);

			printf("str2=%s\n", str2);
		/*if the string is alphanumeric we need to look up the symbol */
		if (str2 != NULL && utility_isalpha(str2) == 0) { //NOTE string is func arg
			SymtabElt *e = (SymtabElt *)malloc(sizeof(SymtabElt));
			e->address = 3000 + j;//heapmax_global;//FIXME 3000 ++ globally;
			//heapmax_global += 2;
			e->pn = 3000 + j;
			
			e->type = FUNCARG;//NOTE nil types are not nil but are searched for at runtime for dynamic binding
			e->Integer = NIL;	
			e->Float = NIL;	
			e->Character = 0;//NIL;	
			e->Null = 0;//NIL;	
			e->String = NULL;//NIL;		
			e->List = NULL;			
			add_symtabname_withaddress(&str2, &e); //NOTE add a single name (func arg)
		} else if (str2 != NULL && utility_isdigit(str2) == 0) { //NOTE string is func arg
			fprintf(stdout, "% unknown function argument : is a digit : %s\n", str2);
		} else if (utility_islist(str2) == 0) {
			fprintf(stdout, "% unknown function argument : is a list : %s\n", str2);
		} else {
			fprintf(stdout, "% unknown function argument : type : %s %d\n", str2, i);
		}	
	}
//	fclose(fp);
//	free(str);
	return 0;
}


/*
* Lists are stored at 4000
*/
int as1_write_listorfunction(char *opexp)
{
	FILE *fp;
	int i = 0, j = 0;
	printf("writing list or function...");	
	int tempmax = heapmax_global;

	if ((fp = fopen("./code.s", "a+")) < 0) {

		printf("neslisp error - Cannot open code output file\n");
		exit(99);

	}

	if (fseek(fp, 0, SEEK_END) < 0) {

		printf("neslisp error - Cannot seek in code output file\n");
	}

	/* jump out if there are no arguments */
	if (opexp == NULL)
		return 0;//NOTE return empty list ?
	/* put all arguments in str */	
	char *str = opexp;//(char *)malloc(1024);
	int len = 0;
	for ( ; len < strlen(str)-1; len++) {
		char *str2 = (char *)malloc(1024);
		getarg(&str, &len, str2);	
		
		/*if the string is alphanumeric we need to look up the symbol */
	
		if (str2 != NULL && utility_isalpha(str2) == 0 && strlen(str2) > 0) {
			SymtabElt *se = NULL;
			get_symtabname(&str2, &se);
			if (se == NULL) {
				fprintf(stdout, "% undefined indentifier : %s\n", str2);
			} else {
				if (se->type == FUNC) {
				}
			}				
		} else if (utility_isdigit(str2) == 0 && strlen(str2) > 0) {//FIXME heapmax
			int n = atoi(str2);		
			fprintf(fp, "ldx #%d\n", n);
			fprintf(fp, "stx $%d\n", 3000+j);
			//heapmax_global += 2;
			//i++;///NOTE
		} else if (utility_islist(str2) == 0) {
			as1_write_list(str2,opexp); 
		} else {
			fprintf(stdout, "% unknown type : %s\n", str2);
		}	
		free(str2);	
	}

	fprintf(fp, "sta $%d\n", 6000);//FIXME stack;
	//free(str);
/*
	SymtabElt *e = (SymtabElt *)malloc(sizeof(SymtabElt));
	e->address = tempmax; 
	e->pn = e->address;
	e->type = LIST;//NOTE nil types are not nil but are searched for at runtime for dynamic binding
	e->Integer = NIL;	
	e->Float = NIL;	
	e->Character = NIL;	
	e->Null = NULL;	
	e->String = NULL;		
	e->List = (List *)malloc(sizeof(List));			
	e->List->length = tempmax - heapmax_global; 
*/
}



int as1_write_equalthan(const char **lispfilecontents, int *lispfileindex)
{
	FILE *fp;
	int i,j = 0;
	char *opexp;
	utility_skip_whitespace_newlines(lispfilecontents, strlen(*lispfilecontents), lispfileindex); 
	getarg_until_parens(lispfilecontents, lispfileindex, &opexp);//FIXME *
	printf("writing equalthan ...\n");	


	if ((fp = fopen("./code.s", "a+")) < 0) {

		printf("neslisp error - Cannot open code output file\n");
		exit(99);

	}

	if (fseek(fp, 0, SEEK_END) < 0) {

		printf("neslisp error - Cannot seek in code output file\n");
		exit(99);

	}
	fprintf(fp, "sta #0\n");

	for (j = 0, i = strlen(opexp); i >= 0; i--, j++) {
	
	char *str;
	getstring(&opexp, &i,&str);

	if (utility_isdigit(str) == 0) {	
		int n = atoi(str);
		fprintf(fp, "lda #%d\n", n);
		fprintf(fp, "sta $%d\n", 1000+j);//FIXME if cond;
	} else if (utility_isalpha(str) == 0) {	
		SymtabElt *se = NULL;//FIXME return it;
		get_symtabname(&str, &se);
		if (se == NULL) {
			fprintf(stdout, "%equal than % undefined identifier : %s %s\n", str, str);
		} else if (se->type != INTEGER && se->type != FLOAT && se->type != FUNCARG && se->type != LOOPARG) {
			fprintf(stdout, "%equal than = % wrong type argument : %s %s\n", opexp, opexp);	
			exit(99);
		} else {
			fprintf(fp, "lda $%d\n", se->address);
			fprintf(fp, "sta $%d\n", 1000+j);
		}		
	} else if (utility_islist(str) == 0) {
		as1_write_list(str,opexp);
	} 
	j++;
	i--;
	free(str);
	}


	fprintf(fp, "cmp $%d\n", 1000);//FIXME2 fixed value
	fprintf(fp, "sta $%d\n", 1000);
	fprintf(fp, "bne compare%d\n", labelcounter);
	

	fclose(fp);
	return 0;
}



int as1_write_greaterthan(const char **lispfilecontents, int *lispfileindex)
{
	FILE *fp;
	int i,j = 0;
	char *opexp;
	utility_skip_whitespace_newlines(lispfilecontents, strlen(*lispfilecontents), lispfileindex); 
	getarg_until_parens(lispfilecontents, lispfileindex, &opexp);//FIXME *
	printf("writing greaterthan ...\n");	


	if ((fp = fopen("./code.s", "a+")) < 0) {

		printf("neslisp error - Cannot open code output file\n");
		exit(99);

	}

	if (fseek(fp, 0, SEEK_END) < 0) {

		printf("neslisp error - Cannot seek in code output file\n");
		exit(99);

	}
	fprintf(fp, "sta #0\n");

	for (j = 0, i = strlen(opexp); i >= 0; i--, j++) {//NOTE opexp has been chomped : -2
	
	char *str;// = (char *)malloc(1024);	
	getstring(&opexp, &i,&str);

	if (utility_isdigit(str) == 0) {	
		int n = atoi(str);
		fprintf(fp, "lda #%d\n", n);
		fprintf(fp, "sta $%d\n", 1000+j);//FIXME if cond;
	} else if (utility_isalpha(str) == 0) {	
		SymtabElt *se = NULL;//FIXME return it;
		get_symtabname(&str, &se);
		if (se == NULL) {
			fprintf(stdout, "%greater than % undefined identifier : %s %s\n", str, str);
		} else if (se->type != INTEGER && se->type != FLOAT && se->type != FUNCARG && se->type != LOOPARG) {
			fprintf(stdout, "%greater than > % wrong type argument : %s %s\n", opexp, opexp);	
			exit(99);
		} else {
			fprintf(fp, "lda $%d\n", se->address);
			fprintf(fp, "sta $%d\n", 1000+j);
		}		
	} else if (utility_islist(str) == 0) {
		as1_write_list(str,opexp);
	} 
	j++;
	i--;
	free(str);
	}


	fprintf(fp, "cmp $%d\n", 1000);//FIXME2 fixed value
	fprintf(fp, "sta $%d\n", 1000);
	fprintf(fp, "bne compare%d\n", labelcounter);
	

	fclose(fp);
	return 0;
}



//fprintf(fp, "bne when%d\n", labelcounter);//result of < is stored in 1000

int as1_write_lessthan(const char **lispfilecontents, int *lispfileindex)
{
	FILE *fp;
	int i,j = 0;
	char *opexp;
	utility_skip_whitespace_newlines(lispfilecontents, strlen(*lispfilecontents), lispfileindex); 
	getarg_until_parens(lispfilecontents, lispfileindex, &opexp);//FIXME *
	printf("writing lessthan ...\n");	


	if ((fp = fopen("./code.s", "a+")) < 0) {

		printf("neslisp error - Cannot open code output file\n");
		exit(99);

	}

	if (fseek(fp, 0, SEEK_END) < 0) {

		printf("neslisp error - Cannot seek in code output file\n");
		exit(99);

	}
	fprintf(fp, "sta #0\n");

	for (j = 0, i = 0; i < strlen(opexp); i++, j++) {//NOTE opexp has been chomped : -2
	
	char *str;
	//getstring(&opexp, &i,&str);
	getarg(&opexp, &i,&str);


	if (utility_isdigit(str) == 0) {	
		int n = atoi(str);
		fprintf(fp, "lda #%d\n", n);
		fprintf(fp, "stx $%d\n", 1000+j);//FIXME if cond;
	} else if (utility_isalpha(str) == 0) {	
		SymtabElt *se = NULL;//FIXME return it;
		get_symtabname(&str, &se);
		if (se == NULL) {
			fprintf(stdout, "%lessthan % undefined identifier : %s %s\n", str, str);
		} else if (se->type != INTEGER && se->type != FLOAT && se->type != FUNCARG && se->type != LOOPARG) {
			fprintf(stdout, "%lessthan < % wrong type argument : %s %s\n", opexp, opexp);	
			exit(99);
		} else {
			fprintf(fp, "lda $%d\n", se->address);
			fprintf(fp, "sta $%d\n", 1000+j);
		}		
	} else if (utility_islist(str) == 0) {
		as1_write_list(str,opexp);
	} 
	}


	fprintf(fp, "cmp $%d\n", 1000);
	fprintf(fp, "sta $%d\n", 1000);
	fprintf(fp, "bne compare%d\n", labelcounter);
	

	fclose(fp);
	return 0;
}





int as1_write_when(const char **lispfilecontents, int *lispfileindex)
{
	FILE *fp;
	int i,j = 0;
	char *opexp;
	utility_skip_whitespace_newlines(lispfilecontents, strlen(*lispfilecontents), lispfileindex); 
	getarg_until_parens(lispfilecontents, lispfileindex, &opexp);//FIXME *
	printf("writing when ...\n");	


	if ((fp = fopen("./code.s", "a+")) < 0) {

		printf("nescc error - Cannot open code output file\n");
		exit(99);

	}

	if (fseek(fp, 0, SEEK_END) < 0) {

		printf("nescc error - Cannot seek in code output file\n");
		exit(99);

	}


	for (j = 0, i = strlen(opexp); i >= 0; i--, j++) {//NOTE opexp has been chomped : -2
	
	char *str;
	getstring(&opexp, &i,&str);


	/* read if conditional and return */	

	if (opexp[1] == '<') {
		lispfileindex -= strlen(opexp);
		as1_write_lessthan(lispfilecontents, lispfileindex);
		//fprintf(fp, "bne when%d\n", labelcounter);//result of < is stored in 1000


		return 1;
	} else if (opexp[1] == '>') {
		lispfileindex -= strlen(opexp);
		as1_write_greaterthan(lispfilecontents, lispfileindex);
		//fprintf(fp, "bne when%d\n", labelcounter);//result of < is stored in 1000
		return 1;
	} else if (opexp[1] == '=') {
		lispfileindex -= strlen(opexp);
		as1_write_equalthan(lispfilecontents, lispfileindex);
		//fprintf(fp, "bne when%d\n", labelcounter);//result of < is stored in 1000
		return 1;
	} else if (utility_isdigit(str) == 0) {	
		int n = atoi(str);
		fprintf(fp, "sta $%d\n", 1000+j);
		i--;
	} else if (utility_isalpha(str) == 0) {	
		SymtabElt *se = NULL;//FIXME return it;
		get_symtabname(&str, &se);
		if (se == NULL) {
			fprintf(stdout, "%lessthan % undefined identifier : %s %s\n", str, str);
		} else if (se->type != INTEGER && se->type != FLOAT && se->type != FUNCARG && se->type != LOOPARG) {
			fprintf(stdout, "%when % wrong type argument : %s %s\n", opexp, opexp);	
			exit(99);
		} else {
			fprintf(fp, "lda $%d\n", se->address);
			fprintf(fp, "sta $%d\n", 1000+j);
		}		
	} else if (utility_islist(str) == 0) {
		as1_write_list(str,opexp);
	} 
	j++;
	i--;
	free(str);
	}

	fprintf(fp, "bne when%d\n", labelcounter);//result of < is stored in 1000

	fclose(fp);
	return 0;
}





int as1_write_if(const char **lispfilecontents, int *lispfileindex)
{
	FILE *fp;
	int i,j = 0;
	char *opexp;
	utility_skip_whitespace_newlines(lispfilecontents, strlen(*lispfilecontents), lispfileindex); 
	getarg_until_parens(lispfilecontents, lispfileindex, &opexp);//FIXME *
	printf("writing if ...opexp=%s\n", opexp);	


	if ((fp = fopen("./code.s", "a+")) < 0) {

		printf("nescc error - Cannot open code output file\n");
		exit(99);

	}

	if (fseek(fp, 0, SEEK_END) < 0) {

		printf("nescc error - Cannot seek in code output file\n");
		exit(99);

	}


	for (j = 0, i = 0; i < strlen(opexp); i++, j++) {//NOTE opexp has been chomped : -2
	
	char *str;
	//getstring(&opexp, &i,&str);
	getarg_until_parens(&opexp, &i,&str);//33333333333333;

	/* read if conditional and return */	

	if (opexp[1] == '<') {
		printf("lispfileindex=%s index=%d str=%s\n", *lispfilecontents, *lispfileindex, str);
		*lispfileindex -= strlen(str);//3333333333strlen(opexp);
		//*lispfileindex -= strlen(str);
		*lispfileindex +=2;//333333333333
		utility_skip_whitespace_newlines(lispfilecontents, strlen(*lispfilecontents), lispfileindex); 
		printf("lispfileindex=%s index=%d str=%s\n", *lispfilecontents, *lispfileindex, str);
		as1_write_lessthan(lispfilecontents, lispfileindex);
		//fprintf(fp, "bne GNU%d\n", labelcounter);//result of < is stored in 1000
		return 1;
	} else if (opexp[1] == '>') {
		*lispfileindex -= strlen(opexp);
		*lispfileindex +=2;//333333333333
		utility_skip_whitespace_newlines(lispfilecontents, strlen(*lispfilecontents), lispfileindex); 
		as1_write_greaterthan(lispfilecontents, lispfileindex);
		//fprintf(fp, "bne if%d\n", labelcounter);//result of < is stored in 1000
		return 1;
	} else if (opexp[1] == '=') {
		*lispfileindex -= strlen(opexp);
		*lispfileindex +=2;//333333333333
		utility_skip_whitespace_newlines(lispfilecontents, strlen(*lispfilecontents), lispfileindex); 
		as1_write_equalthan(lispfilecontents, lispfileindex);
		//fprintf(fp, "bne if%d\n", labelcounter);//result of < is stored in 1000
		return 1;
	} else if (utility_isdigit(str) == 0) {	
		int n = atoi(str);
		//fprintf(fp, "sta $%d\n", 1000+j);
		i--;
	} else if (utility_isalpha(str) == 0) {	
		SymtabElt *se = NULL;//FIXME return it;
		get_symtabname(&str, &se);
		if (se == NULL) {
			fprintf(stdout, "%lessthan % undefined identifier : %s %s\n", str, str);
		} else if (se->type != INTEGER && se->type != FLOAT && se->type != FUNCARG && se->type != LOOPARG) {
			fprintf(stdout, "%when % wrong type argument : %s %s\n", opexp, opexp);	
			exit(99);
		} else {
			fprintf(fp, "lda $%d\n", se->address);
			fprintf(fp, "sta $%d\n", 1000+j);
		}		
	} else if (utility_islist(str) == 0) {
		as1_write_list(str,opexp);
	} 
	j++;
	i--;
	free(str);
	}


	fclose(fp);
	return 0;
}








int as1_write_setq(const char **lispfilecontents, int *lispfileindex)//char *name, char *opexp)
{
	FILE *fp;
	char *name;
	char *opexp;
	char *str;
	printf("writing setq...\n");

	utility_skip_whitespace_newlines(lispfilecontents, strlen(*lispfilecontents), lispfileindex); 
	getarg(lispfilecontents, lispfileindex, &name);
	utility_skip_whitespace_newlines(lispfilecontents, strlen(*lispfilecontents), lispfileindex); 
//FIXME	tullariscgetarg_until_parens(lispfilecontents, lispfileindex, &opexp);
	getarg_until_parens(lispfilecontents, lispfileindex, &opexp);


	if ((fp = fopen("./code.s", "a+")) < 0) {

		printf("neslisp error - Cannot open code output file\n");
		exit(99);

	}

	if (fseek(fp, 0, SEEK_END) < 0) {

		printf("neslisp error - Cannot seek in code output file\n");
		exit(99);

	}


	//opexp[strlen(opexp)-1] = '\0';
		printf("OPEXP=%s\n", opexp);
	if (utility_isdigit(opexp) == 0) {
		SymtabElt *e = (SymtabElt *)malloc(sizeof(SymtabElt));
		add_symtabname(*name, &e);


		//getarg_until_parens(opexp, &str); //getintsolo(opexp);
		//int n = atoi(str); //getintsolo(opexp);
		//int n = getintsolo(opexp);
		int n = atoi(opexp);
		make_integer(&e, n); 
		fprintf(fp, "ldx #%d\n", n);
		fprintf(fp, "stx $%d\n", e->address);

	} else if (utility_isalpha(opexp) == 0) {//FIXME lists other than integer or alpha lookup
		SymtabElt *se;// = (SymtabElt *)malloc(sizeof(SymtabElt));
		SymtabElt *e = (SymtabElt *)malloc(sizeof(SymtabElt));
		add_symtabname(&name, &e);
		char *str2 = (char *)malloc(1024);
		getstringsolo(opexp, str2);
		get_symtabname(&str2, &se);
		fprintf(fp, "ldx $%d\n", se->address);
		fprintf(fp, "stx $%d\n", e->address);
		free(str2);	
	
	} else if (utility_islist(opexp)) {
		as1_write_list(name, opexp);
		//make_list(&e, n); 
		//fprintf(fp, "ldx #%d\n", n);
		//fprintf(fp, "stx $%d\n", e->address);
	} 
	fclose(fp);
	return 0;
}


/*
* Lists are stored at 4000
*/
int as1_write_list(const char **lispfilecontents, int *lispfileindex)
{
	FILE *fp;
	int i = 0, j = 0;
	int tempmax = heapmax_global;
	char *opexp;

	utility_skip_whitespace_newlines(lispfilecontents, strlen(*lispfilecontents), lispfileindex); 
	getarg_until_parens(lispfilecontents, lispfileindex, &opexp);//FIXME *
	printf("writing list...opexp=%s\n", opexp);	
	if ((fp = fopen("./code.s", "a+")) < 0) {

		printf("neslisp error - Cannot open code output file\n");
		exit(99);

	}

	if (fseek(fp, 0, SEEK_END) < 0) {

		printf("neslisp error - Cannot seek in code output file\n");
	}

	/* jump out if there are no arguments */
	if (opexp == NULL)
		return 0;//NOTE return empty list ?

	/* put all arguments in str */	

	char *str = opexp;
	int len = 0;

	///FIXME2utility_skip_whitespace_newlines_parens(&opexp, strlen(opexp), &len); 

	for ( i = 1; i < strlen(opexp); i++) {//NOTE2 i = 1
		char *str2;
		getarg(&opexp, &i, &str2);	
		
		/*if the string is alphanumeric we need to look up the symbol */
	
		if (str2 != NULL && utility_isalpha(str2) == 0 && strlen(str2) > 0) {
			SymtabElt *se = NULL;
			get_symtabname(&str2, &se);
			if (se == NULL) {
				fprintf(stdout, "% undefined indentifier : %s\n", str2);
			} else {
			}				
		} else if (utility_isdigit(str2) == 0 && strlen(str2) > 0) {//FIXME heapmax
			int n = atoi(str2);		
			fprintf(fp, "ldx #%d\n", n);
			fprintf(fp, "stx $%d\n", 4000+j);
			j++;///NOTE
		} else if (utility_islist(str2) == 0) {
			//FIXME2 as1_write_list(str2,opexp); 
		} else {
			fprintf(stdout, "% unknown type : %s\n", str2);
		}	
		free(str2);	
	}


	SymtabElt *e = (SymtabElt *)malloc(sizeof(SymtabElt));
	e->address = tempmax; 
	e->pn = e->address;
	e->type = LIST;//NOTE nil types are not nil but are searched for at runtime for dynamic binding
	e->Integer = NIL;	
	e->Float = NIL;	
	e->Character = 0;	
	e->Null = NULL;	
	e->String = NULL;		
	e->List = (List *)malloc(sizeof(List));			
	e->List->length = tempmax - heapmax_global; 
	char *name = "list1";//FIXME2;
	add_symtabname_withaddress(&name, &e);

}

int as1_write_asm(const char **lispfilecontents, int *lispfileindex)
{
	FILE *fp;
	char *opexp;

	utility_skip_whitespace_newlines(lispfilecontents, strlen(*lispfilecontents), lispfileindex); 
	getarg_until_parens(lispfilecontents, lispfileindex, &opexp);//FIXME *
	printf("writing asm...opexp=%s\n", opexp);	
	if ((fp = fopen("./code.s", "a+")) < 0) {

		printf("neslisp error - Cannot open code output file\n");
		exit(99);

	}

	if (fseek(fp, 0, SEEK_END) < 0) {

		printf("neslisp error - Cannot seek in code output file\n");
	}

	/* jump out if there are no arguments */
	if (opexp == NULL)
		return 0;//NOTE return empty list ?

	/* put all arguments in str */	
	opexp[0] = '\n';
	fprintf(fp, "%s\n", opexp);
}


#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "symboltable.h"
#include "moose.h"

int moose_match()
{
	int i = 0;
	char *lispfilecontents;
	int lispfilelength = 0;
	char *configfilecontents;
	int configfilelength = 0;
	int configfileindex = 0;
	int lispfileindex = 0;
	char *dlfunction;
	char *lastfunctionname;


	make_stack(&stack_global); 

	moose_getfilelength(&lispfilelength, "./moose.lisp");
	moose_readfile(&lispfilecontents, lispfilelength, "./moose.lisp"); 

	moose_getfilelength(&configfilelength, "./moose.config");
	moose_readfile(&configfilecontents, configfilelength, "./moose.config"); 


	for ( ; lispfileindex < lispfilelength-1; ) {

		skip_whitespace_newlines(&lispfilecontents, lispfilelength, &lispfileindex); 
		char *str = NULL;
		if (moose_getstring(&lispfilecontents, lispfilelength, &str, &lispfileindex) < 0) {

			printf("+++ Finished parsing\n");	

		}

		if (configfileindex >= configfilelength) {
		//	configfileindex = 0;	
		}	
	
		for ( ;; ) {
			char *pattern = NULL, *patternstr = NULL;
			dlfunction = NULL;
			if (moose_getpattern(&configfilecontents, configfilelength, &pattern,&patternstr, &configfileindex, &dlfunction) < 0) {
				configfileindex = 0;
				break;
			}

	
			if (strncmp(str, patternstr, strlen(patternstr)) == 0 && strlen(patternstr) > 0 && strlen(pattern) > 0) { //FIXME strlen pattern can not be zero if we loop all the time through the patterns

				if (strlen(patternstr) < strlen(str) && strlen(str) > 0 && strlen(pattern) > 0 && strlen(patternstr) > 0) {

					lispfileindex = lispfileindex - (strlen(str) - strlen(patternstr));
				//	free(pattern);
				//	free(patternstr);
					//break; //FIXME free
	
				}
				stack_push(&stack_global, &patternstr, &str);
				//stack_print(&stack_global);
				//lispfileindex += strlen(patternstr);
				//lispfileindex += 1;
				configfileindex = 0;	
				printf("MATCH=%s dlfunction=%s\n", str, dlfunction);

				//if (dlfunction != NULL && strlen(dlfunction) > 0) {
					switch(atoi(pattern)){
					case 1:{
						stack_pop(&stack_global);
						break;
					}
					case 2:{
						printf("popped\n");
						char *retpatternstr = NULL;
						char *retnamestr = NULL;
						stack_pop(&stack_global);
						stack_pop_andreturn(&stack_global, &retpatternstr, &retnamestr);
						if (retpatternstr != NULL && strlen((char *)retpatternstr) > 0) {

							if (strncmp((char *)retpatternstr, LOOP, strlen(LOOP)) == 0) {

							printf("LOOP POP RETURN=%s\n", (char *)retpatternstr);
								as1_write_loopend();
							} else if (strncmp((char *)retpatternstr, WHEN, strlen(WHEN)) == 0) {
							printf("WHEN POP RETURN=%s\n", (char *)retpatternstr);
							stack_print(&stack_global);
							as1_write_whenend();	
							char *elsestr = (char *)malloc(1024);
							elsestr = strdup(WHENELSE);
							stack_push(&stack_global, &elsestr, &elsestr);
										
							} else if (strncmp((char *)retpatternstr, IF, strlen(IF)) == 0) {
							printf("IF POP RETURN=%s\n", (char *)retpatternstr);
							stack_print(&stack_global);	
							as1_write_iffirstclauseend(&lastfunctionname, atoi(retnamestr));	
							//FIXME1
							char *elsestr = (char *)malloc(1024);
							elsestr = strdup(IFELSE);
							char *elsestr2 = (char *)malloc(1024);
							sprintf(elsestr2, "%d\0", labelcounter); 
							stack_push(&stack_global, &elsestr, &elsestr2);
							} else if (strncmp((char *)retpatternstr, IFELSE, strlen(IFELSE)) == 0) {
							labelcounter++;
							printf("ELSE POP RETURN=%s\n", (char *)retpatternstr);
					
							as1_write_ifsecondclauseend(&lastfunctionname, atoi(retnamestr));	
							char *elsestr = (char *)malloc(1024);
							elsestr = strdup(IFTHIRD);
							stack_push(&stack_global, &elsestr, &elsestr);
							} else if (strncmp((char *)retpatternstr, WHENELSE, strlen(WHENELSE)) == 0) {
							printf("WHEN ELSE POP RETURN=%s\n", (char *)retpatternstr);
							as1_write_whenendsecond(&lastfunctionname);	
							} else if (strncmp((char *)retpatternstr, IFTHIRD, strlen(IFTHIRD)) == 0) {
							//labelcounter++;
							printf("IF THIRD POP RETURN=%s\n", (char *)retpatternstr);
							as1_write_ifclausethird(&lastfunctionname, atoi(retnamestr));	
							} else if (strncmp((char *)retpatternstr, DEFUN, strlen(DEFUN)) == 0) {
							printf("DEFUN POP RETURN=%s\n", (char *)retpatternstr);
							stack_print(&stack_global);
							as1_write_functionend(&lastfunctionname);	
							}			
						}
						break; 	
					}
					case 3:{
						as1_write_setq(&lispfilecontents, &lispfileindex);
						stack_pop(&stack_global);
						break; 	
					}
					case 4:{
						labelcounter++;	
						as1_write_functionheader(&lispfilecontents, &lispfileindex);
						//////stack_pop(&stack_global);
						break; 	
					}
					case 5:{
						as1_write_operator_plus(&lispfilecontents, &lispfileindex);
						stack_pop(&stack_global);
						break; 	
					}
					case 6:{
						labelcounter++;	
						as1_write_loop(&lispfilecontents, &lispfileindex);
						break; 	
					}
					case 7:{
						labelcounter++;	
						as1_write_when(&lispfilecontents, &lispfileindex);
						break; 	
					}
					case 8:{
						as1_write_lessthan(&lispfilecontents, &lispfileindex);
						stack_pop(&stack_global);
						break; 	
					}
					case 9:{
						as1_write_greaterthan(&lispfilecontents, &lispfileindex);
						stack_pop(&stack_global);
						break; 	
					}
					case 10:{
						as1_write_equalthan(&lispfilecontents, &lispfileindex);
						stack_pop(&stack_global);
						break; 	
					}
					case 11:{
						as1_write_operator_minus(&lispfilecontents, &lispfileindex);
						stack_pop(&stack_global);
						break; 	
					}
					case 12:{
						labelcounter++;	
						as1_write_if(&lispfilecontents, &lispfileindex);
						break; 	
					}
					case 13:{
						as1_write_list(&lispfilecontents, &lispfileindex);
						break; 	
					}
					case 14:{
						as1_write_asm(&lispfilecontents, &lispfileindex);
						stack_pop(&stack_global);
						break; 	
					}
					default:{
						break;
					}
					}

						


				//}	
				//if (pattern != NULL) free(pattern);
				//if (patternstr != NULL) free(patternstr);
				break;
	
			} else {
				SymtabElt *e = NULL;
				if (get_symtabname(&str, &e) && e != NULL && e->type == FUNC) {
					lastfunctionname = str;	
					as1_write_functionjump(str, &lispfilecontents, &lispfileindex);
					break;	
				}
			}
			//free(pattern);
			//free(patternstr);
		}
		//free(str);	
	}
}

int skip_whitespace_newlines(const char **lispfilecontents, const int lispfilelength, int *index) 
{
	int j = 0;
	char c;
	for (j = 0; *index < lispfilelength && (c = (*lispfilecontents)[(*index)]) == '\n' || c == ' '; j++) {
		(*index) ++;
	}
	return 1;
}


int moose_getfilelength(int *length, const char *filename)
{
	int i = 0;
	char c;
	FILE *fp;
	if ((fp = fopen(filename, "r")) == NULL)
		return -1;

	for (i = 0; (c = getc(fp)) != EOF; i++ ) 
		;

	(*length) = i;	
	fclose(fp);	
	return 1;
}

int moose_readfile(char **filecontents, const int lispfilelength, const char *filename)
{

	int i = 0;
	char c = '\0';
	FILE *fp;

	if ((fp = fopen(filename, "r")) == NULL)
		return -1;

	(*filecontents) = (char *)malloc(lispfilelength);

	for (i = 0; (c = getc(fp)) != EOF; i++ ) 
		(*filecontents)[i] = (char)c;
	 
	fclose(fp);
	return 1;
}


int moose_getstring(const char **lispfilecontents, const int lispfilelength, char **retstr, int *index)
{

	int i = 0, j = 0;
	char c;
	(*retstr) = (char *)malloc(BUFSIZE);
	memset(*retstr, 0 ,BUFSIZE);
	for (i = 0; i < lispfilelength && (c = (*lispfilecontents)[(*index)]) != ' ' && c != '\n'; i++) {
		(*retstr)[i] = (char)c;
		/*if ((*lispfilecontents)[*index]	== '(') {
			(*index)++;
			return 1;//moose_getstring(lispfilecontents, lispfilelength, retstr, index);
		}	
		*/
		(*index)++;
	
	} 
	return 1;

}

int moose_getpattern(const char **configfilecontents, const int configfilelength, char **pattern, char **patternstr, int *index, char **dlfunction)
{
	*pattern = (char *)malloc(BUFSIZE); //FIXME BUFSIZE
	*patternstr = (char *)malloc(BUFSIZE);
	memset(*pattern, 0 ,BUFSIZE);
	memset(*patternstr, 0 ,BUFSIZE);
	int i = 0, j = 0, k = 0;
	char c;
	(*dlfunction) = NULL;	
	for (i = *index, j = 0; i < configfilelength && (c = (*configfilecontents)[i]) != ' '; i++, j++) //PARSE only 2 in a PATTERN, let the write_ functions do the rest
		(*pattern)[j] = (char)c;

	*index += j;
	
	for (; i < configfilelength && (*configfilecontents)[i] == ' '; i++) {
		
	}
	//i++;	
	for (j = 0; i < configfilelength && (c = (*configfilecontents)[i]) != ' ' && c != '\n'; i++, j++) { 
		(*patternstr)[j] = (char)c;
	}
	*index += j;
	for (j = 0; i < configfilelength && (c = (*configfilecontents)[i]) == '\n' || c == ' '; i++, j++) {
		
	}
	*index += j;

	if (i < configfilelength && (*configfilecontents)[i-1] == '\n' ) {
		*index += 1;//NOTE default newline
		return 1;	
	}	
	
	*dlfunction = (char *)malloc(BUFSIZE);
	memset(*dlfunction, 0 ,BUFSIZE);
	for (j = 0; i < configfilelength && (c = (*configfilecontents)[i]) != ' ' && c != '\n'; i++, j++) {

		(*dlfunction)[j] = (char)c;

	}
	(*dlfunction)[j] = '\0';


	*index += j;

	for (j = 0; i < configfilelength && (c = (*configfilecontents)[i] == '\n' || c != ' '); i++, j++)
		;

	*index += j;
	*index += 1;//NOTE default newline

	return 1;
}

//#if 0 


int main()
{

	moose_match();


	return 0;

}	
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include "stack.h"

int make_stack(Stack **st)
{
	*st = (Stack *)malloc(sizeof(Stack));
	(*st)->length = 0;
	(*st)->stack = NULL;

}		

int stack_push(Stack **st, char **e, char **name)
{
	int i = 0;
	if (*st == NULL)
		return -1;	

	StackElt *se = (StackElt *)malloc(sizeof(StackElt));

	if (se == NULL) return -1;

	se->elt = strdup(*e);
	se->name = strdup(*name);
	se->next = (*st)->stack;
	(*st)->stack = se;
	(*st)->length ++;

	printf("STACK=%s\n",se->elt);
	
	return 1;
}

int stack_pop_andreturn(Stack **st, char **ret, char **retname) 
{
	int i = 0;
	if (*st == NULL)
		return -1;	

	StackElt *tmp = (*st)->stack;
	if (tmp != NULL) {
		 *ret = (*st)->stack->elt;
		 *retname = (*st)->stack->name;
	 } else { 
		 *ret = NULL;
		return -1;
		}
	//*ret = malloc(sizeof(*tmp));
	//memcpy(*ret, tmp, sizeof(tmp));
	(*st)->stack = tmp->next;	
	(*st)->length --;
	return 1;
}

int stack_pop(Stack **st) 
{
	int i = 0;
	if (*st == NULL)
		return -1;	

	StackElt *tmp = (*st)->stack;
	(*st)->stack = tmp->next;	

	free(tmp);
	(*st)->length --;

	return 1;
}

void stack_print(Stack **st)
{
	int i = 0;
	StackElt *tmp = (*st)->stack;
	for (i = 0; i < (*st)->length - 1; i++) {
		fprintf(stdout, "Stack print : %s\n", (char *)(*st)->stack);//FIXME char * -> void * 
		tmp = tmp->next;	

	}
	
}

#if 0 
int main()
{

	Stack *s;
	int i = 12;	
	make_stack(&s);
	char *e = &i;
	stack_push(&s, e); 

	char *e2 = &i;
	stack_push(&s, e2); 
	
	char *e3 = &i;
	stack_push(&s, e2); 
	
	char *e4 = &i;
	stack_push(&s, e2); 

	stack_print(&s);
	
	stack_pop(&s);
	stack_pop(&s);
	
	stack_print(&s);

	return 0;
}
#endif
#include "storage.h"

int store_function(int (*f)(char *, char *), char *argstr1, char *argstr2)
{
	FunctionstackElt *e = (FunctionstackElt *)malloc(sizeof(FunctionstackElt));
	e->f = f;
	e->arg1 = argstr1;
	e->arg2 = argstr2;
	functionstack_global[functionstackpointer_global++] = e;
}

int emit_functions()
{
	int i = 0;
	for (i = 0; i < functionstackpointer_global; i++) {	
		FunctionstackElt *e = functionstack_global[0];
		(e->f)(e->arg1,e->arg2);
	}
}


/*
# Copyright (C) Johan Ceuppens 2009,2010 
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 2 of the License, or
# (at your option) any later version.

# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.

# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>

#include "symboltable.h"

char *get1(char *str)
{
	int i;
	char *retstr = (char *)malloc(strlen(str)+1);//FIXME
	for (i = 0; str[i] != '\0' && str[i] != ' ' && str[i] != ';' && str[i] != ',' /*&& 
		((str[i] >= 65 && str[i] <= 90) || (str[i] >= 97 && str[i] <= 122))*/; i++) {

		//printf("++++++++++++++++++++>%c\n", str[i]);

		retstr[i] = str[i];	

	}
	retstr[strlen(str)] = '\0';
	return retstr;
}

int make_symtab ()
{
	printf("Making symtab...\n");
//	heapmax_global = 2;
	return 0;
}

/*
* Symtab elt adding functions
*/
int add_symtab(SymtabElt **se)
{

	symtab_global[(*se)->address] = (*se);
	
	return 1;

}

int add_symtabname(char **name, SymtabElt **se)
{
	int i;
	SymtabNameElt *sne = (SymtabNameElt *)malloc(sizeof(SymtabNameElt));
	sne->name = strdup(*name);
	(*se)->address = heapmax_global;//sne->address;//FIXME strdup ?;
	sne->address = heapmax_global;	
	symtabname_global[heapmaxname_global] = sne;
	heapmaxname_global += 1;	
	heapmax_global += 2;	

	add_symtab(se);	
	return 0;	
}
int add_symtabname_withaddress(char **name, SymtabElt **se)
{
	int i;
	SymtabNameElt *sne = (SymtabNameElt *)malloc(sizeof(SymtabNameElt));
	sne->name = *name;
	sne->address = heapmaxname_global;	
	symtabname_global[heapmaxname_global] = sne;
	heapmaxname_global += 1;	
//	heapmax_global += 2;	
//	(*se)->address = sne->address;//FIXME strdup ?;
	add_symtab(se);	
	return 0;	
}

int get_symtabname(const char **name, SymtabElt **se)
{
	int i = 0;
	SymtabNameElt *sne;
	for (i = 0; i < HEAPSIZE; i++) {
		sne = symtabname_global[i];
		//printf("name=%d\n", sne);
		//printf("HEAPPTR=%d name=%s\n",i, *name);
		if (sne != NULL 
		&&
		*name != NULL
		&&
		strlen(*name) > 0	
		&&/* (comparealpha(sne->name, *name) >= 3 ||*/ 
		strncmp(sne->name, *name, strlen(*name)) == 0)//FIXME 1 -> strlen, only first letter is matched ! 
			break;
	}

	if (i >= HEAPSIZE) { (*se) = NULL; return -1; }
	(*se) = (SymtabElt *)malloc(sizeof(SymtabElt));
	(*se) = symtab_global[sne->address];
	//printf("se addr=%d\n", i/*sne->address*/ );	
	return 1; 
}


/*
void assign(char  *a, char *b)
{

//	isascii((int)b) ? add_symtab_character(*&s,(int)a, b[0]) : assign_number(s, a, atof(b));//mo

	printf("Assigning...%s := %s\n", a , b);

}
*/
#if 0
int main()
{

	Symtab s;
	make_symtab(&s);

	SymtabElt e;
	e.type = INTEGER;
	e.Integer = 123;	

	add_symtab(&e);	
	//print_symtab(&s);
}
#endif
#include <stdio.h>
#include <stdlib.h>
#include "symboltable.h"

int make_integer(SymtabElt **se, int value)
{

	(*se)->type = INTEGER;
	(*se)->Integer = value;	
	(*se)->Float = value;	
	(*se)->Character = 0;	
	(*se)->Null = NULL;
	(*se)->String = (char *)malloc(1024);//FIXME fixed value	
	sprintf((*se)->String, "%d\0", value);

\end{verbatim}
\end{mylisting}


\section{\large Conclusion}


\bibliographystyle{plain}
\bibliography{refs} % refs.bib

\end{document}

}
